/* 
 * Copyright (C)2008 Vladimir Hozjan vladimir.hozjan@gmail.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

/**
* @file TetrisEngineTest.cpp  
*
* Implementation of tests of Tetris
*
* @author Vladimir Hozjan
* @date   28.12.2008 
*
* @remarks VHOZ [28.12.2008]: file created
*/

/////////////////////////////////////////////////////////////////////  LIBRARIES
#include "TetrisEngineTest.h"
#include "tetris.h"
#include <math.h>

// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( TetrisEngineTest );

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

/**
 * @class TestRandomImpl
 * 
 * Null random implementation of random interface
 *
 * @author VHOZ
 *
 * @remarks VHOZ [25.12.2008]: Class created
 */
class TestRandomImpl : public SystemInterface {
public:
  /// Constructor
  TestRandomImpl():mNumber(0){};

  /// Destructor
  virtual ~TestRandomImpl(){};

  /// Setter for number
  void setNumber(int val) { mNumber = val; }

  /// return random number
  virtual int getRandom(int aMaxValue) {
    return mNumber;
  }

  /// return sqrt
  virtual double sqrt(double aVal){
    return ::sqrt(aVal);
  }
private:
  int mNumber;
};

/*static null random object*/
static TestRandomImpl testRandomObject;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

/**
 * setUp
 *
 */
void TetrisEngineTest::setUp() {
  mTetris = new Tetris(testRandomObject);
  mTetris1 = new Tetris(testRandomObject);
  mTetris2 = new Tetris(testRandomObject);
}

/**
 * tearDown
 *
 */
void TetrisEngineTest::tearDown() { 
  delete mTetris;
  delete mTetris1;
  delete mTetris2;
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes1() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,6));
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes2() {
  unsigned short element = 2;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,7));
}

/**
* testElementShapes
*
* Test element shapes
*/
void TetrisEngineTest::testElementShapes3() {
  unsigned short element = 3;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4)); 
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes4() {
  unsigned short element = 4;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes5() {
  unsigned short element = 5;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes6() {
  unsigned short element = 6;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));
}

/**
 * testElementShapes
 *
 * Test element shapes
 */
void TetrisEngineTest::testElementShapes7() {
  unsigned short element = 7;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
}

/**
 * testMoveShapeLeft
 *
 * Test of moveLeft method
 */
void TetrisEngineTest::testMoveShapeLeft() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.moveLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));

  tetrisElement.moveLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,2));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));

  tetrisElement.moveLeft();
  
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));

  tetrisElement.moveLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,-1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,-1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18, 0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,-1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17, 0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,-1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 2));

  tetrisElement.moveLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,-1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,-1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18, 0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,-1));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17, 0));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17, 2));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,-1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 0));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 1));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16, 2));
}

/**
 * testMoveShapeRight
 *
 * long_description
 */
void TetrisEngineTest::testMoveShapeRight() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.moveRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,7));

  tetrisElement.moveRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,6));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,6));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,8));

  tetrisElement.moveRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,9));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,6));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,7));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,9));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,6));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,7));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,9));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,7));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,8));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,9));

  tetrisElement.moveRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,8 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,7 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,8 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,7 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,8 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,7 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,8 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,10));

  tetrisElement.moveRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,7 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,8 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,7 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,8 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,7 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,8 ));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,10));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,7 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,8 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,9 ));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,10));
}

/**
 * testTurnLeft
 *
 * Test left turn
 */
void TetrisEngineTest::testTurnLeft() {
  unsigned short element = 7;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.rotateLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));

  tetrisElement.rotateLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));

  tetrisElement.rotateLeft();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
}

/**
 * testTurnRight
 *
 * Test rotateRight method.
 */
void TetrisEngineTest::testTurnRight() {
  unsigned short element = 7;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.rotateRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));

  tetrisElement.rotateRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));

  tetrisElement.rotateRight();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));

  CPPUNIT_ASSERT_EQUAL(empty, tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element,   tetrisElement.getCell(18,5));

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,5));
}

/**
 * testNextMoveDown
 *
 * Test methods nextMove and moveDown. Additionally test callback methods. 
 */
void TetrisEngineTest::testNextMoveDown() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  tetrisElement.nextMove(); 
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(19,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(18,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(18,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(17,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(17,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(16,6));


  tetrisElement.moveDown();
  
  tetrisElement.moveDown();
  tetrisElement.moveDown();
  tetrisElement.moveDown();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.moveDown();
  tetrisElement.moveDown();
  tetrisElement.moveDown();
  tetrisElement.nextMove();
  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(3,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(3,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(3,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(3,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(2,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(2,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,6));

  tetrisElement.nextMove();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,6));

  tetrisElement.nextMove();
  tetrisElement.moveDown();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,6));
}

/**
 * testDrop
 *
 * Test drop method
 *
 */
void TetrisEngineTest::testDrop() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  tetrisElement.drop();

  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(2,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(1,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,3));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,4));
  CPPUNIT_ASSERT_EQUAL(element, tetrisElement.getCell(0,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(0,6));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,3));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,4));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,5));
  CPPUNIT_ASSERT_EQUAL(empty,   tetrisElement.getCell(-1,6));
}

/**
 * testFullLine
 *
 * Test full line
 */
void TetrisEngineTest::testFullLine() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  testRandomObject.setNumber(element);
  tetrisElement.drop();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.drop();

  int i,j;
  for (i = 0; i < 20; i++) {
    for(j = 0; j < 10; j++) {
      char text[255];
      sprintf(text, "Error at %d:%d", i , j);
      CPPUNIT_ASSERT_EQUAL_MESSAGE(text, (unsigned short)0, tetrisElement.getCell(i,j));
    }
  }
  
  tetrisElement.rotateRight();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveLeft();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveLeft();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveRight();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.drop();
  tetrisElement.rotateRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.moveRight();
  tetrisElement.drop();

  for (i = 0; i < 20; i++) {
    for(j = 0; j < 10; j++) {
      char text[255];
      sprintf(text, "Error at %d:%d", i , j);
      CPPUNIT_ASSERT_EQUAL_MESSAGE(text,(unsigned short)0, tetrisElement.getCell(i,j));
    }
  }
}

/**
 * testPositionChange
 *
 * Test position change callback method.
 */
void TetrisEngineTest::testPositionChange() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  TTetrisFunctor<TetrisEngineTest> elementCallback(this, &TetrisEngineTest::onElementChange);
  TTetrisFunctor<TetrisEngineTest> positionCallback(this, &TetrisEngineTest::onPositionChange);
  tetrisElement.setElementChangeCallback(elementCallback);
  tetrisElement.setPositionChangeCallback(positionCallback);

  mPositionChange = false;
  tetrisElement.nextMove(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.moveDown(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.moveLeft(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.moveRight(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.rotateLeft(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.rotateRight(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);

  mPositionChange = false;
  tetrisElement.drop(); //Position of element is changed and callback is called
  CPPUNIT_ASSERT_EQUAL(true, mPositionChange);
}


/**
 * testElementChange
 *
 * Test element change callback method
 */
void TetrisEngineTest::testElementChange() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  TTetrisFunctor<TetrisEngineTest> elementCallback(this, &TetrisEngineTest::onElementChange);
  TTetrisFunctor<TetrisEngineTest> positionCallback(this, &TetrisEngineTest::onPositionChange);
  tetrisElement.setElementChangeCallback(elementCallback);
  tetrisElement.setPositionChangeCallback(positionCallback);

  mElementChange = false;
  tetrisElement.nextMove(); 
  tetrisElement.moveDown(); 
  tetrisElement.moveLeft(); 
  tetrisElement.moveRight();
  tetrisElement.rotateLeft(); 
  tetrisElement.rotateRight();
  CPPUNIT_ASSERT_EQUAL(false, mElementChange);

  tetrisElement.drop();
  CPPUNIT_ASSERT_EQUAL(true, mElementChange);

  mElementChange = false;
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  tetrisElement.nextMove();
  CPPUNIT_ASSERT_EQUAL(false, mElementChange);
  tetrisElement.nextMove();
  CPPUNIT_ASSERT_EQUAL(true, mElementChange);
}

/**
 * stresTest
 *
 * 
 */
void TetrisEngineTest::stresTest() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  int cnt;
  for (cnt = 0 ; cnt < 500; cnt++) {
    tetrisElement.moveLeft();
    tetrisElement.moveLeft();
    tetrisElement.moveLeft();
    tetrisElement.moveLeft();
    tetrisElement.drop();
    tetrisElement.moveLeft();
    tetrisElement.moveLeft();
    tetrisElement.drop();
    tetrisElement.drop();
    tetrisElement.moveRight();
    tetrisElement.moveRight();
    tetrisElement.drop();
    tetrisElement.moveRight();
    tetrisElement.moveRight();
    tetrisElement.moveRight();
    tetrisElement.moveRight();
    tetrisElement.drop();
  }

  char text[255];
  int i, j;
  for (i = 0; i < 19; i++) {
    for(j = 0; j < 10; j++) {
      sprintf(text, "Error at %d:%d", i , j);
      CPPUNIT_ASSERT_EQUAL_MESSAGE(text,(unsigned short)0, tetrisElement.getCell(i,j));
    }
  }

  CPPUNIT_ASSERT_EQUAL((unsigned short)1000, tetrisElement.getNumberOfLines());
  CPPUNIT_ASSERT_EQUAL((double)2149380, tetrisElement.getScore());
  CPPUNIT_ASSERT_EQUAL((unsigned short)100, tetrisElement.getLevel());
}

/**
 * testIsGameOver
 *
 * Test is game over mechanism.
 */
void TetrisEngineTest::testIsGameOver() {
  unsigned short element = 1;
  unsigned short empty = 0;
  testRandomObject.setNumber(element - 1);
  Tetris tetrisElement(testRandomObject);

  CPPUNIT_ASSERT_EQUAL(false, tetrisElement.isGameOver());
  tetrisElement.nextMove(); 
  tetrisElement.moveDown(); 
  tetrisElement.moveLeft(); 
  tetrisElement.moveRight();
  tetrisElement.rotateLeft(); 
  tetrisElement.rotateRight();
  tetrisElement.drop();
  CPPUNIT_ASSERT_EQUAL(false, tetrisElement.isGameOver());
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  tetrisElement.drop();
  CPPUNIT_ASSERT_EQUAL(false, tetrisElement.isGameOver());
  tetrisElement.drop();
  CPPUNIT_ASSERT_EQUAL(true, tetrisElement.isGameOver());
  tetrisElement.nextMove(); 
  tetrisElement.moveDown(); 
  tetrisElement.moveLeft(); 
  tetrisElement.moveRight();
  tetrisElement.rotateLeft(); 
  tetrisElement.rotateRight();
  tetrisElement.drop();
  CPPUNIT_ASSERT_EQUAL(true, tetrisElement.isGameOver());
}
